Bass degrees#
%load_ext autoreload
%autoreload 2
import os
from collections import Counter, defaultdict
import matplotlib.pyplot as plt
import ms3
import pandas as pd
import plotly.express as px
from dimcat import groupers, plotting
from dimcat.data.resources.utils import make_adjacency_groups
import utils
pd.set_option("display.max_rows", 1000)
pd.set_option("display.max_columns", 500)
RESULTS_PATH = os.path.abspath(os.path.join(utils.OUTPUT_FOLDER, "bass_degrees"))
os.makedirs(RESULTS_PATH, exist_ok=True)
def make_output_path(
filename: str,
extension=None,
path=RESULTS_PATH,
) -> str:
return utils.make_output_path(filename=filename, extension=extension, path=path)
def save_figure_as(
fig, filename, formats=("png", "pdf"), directory=RESULTS_PATH, **kwargs
):
if formats is not None:
for fmt in formats:
plotting.write_image(fig, filename, directory, format=fmt, **kwargs)
else:
plotting.write_image(fig, filename, directory, **kwargs)
Loading data
D = utils.get_dataset("couperin_concerts", corpus_release="v2.2")
D
Dataset
=======
{'inputs': {'basepath': None,
'packages': {'couperin_concerts': ["'couperin_concerts.measures' (MuseScoreMeasures)",
"'couperin_concerts.notes' (MuseScoreNotes)",
"'couperin_concerts.expanded' (MuseScoreHarmonies)",
"'couperin_concerts.chords' (MuseScoreChords)",
"'couperin_concerts.metadata' (Metadata)"]}},
'outputs': {'basepath': None, 'packages': {}},
'pipeline': []}
Grouping data
grouped_D = groupers.ModeGrouper().process(D)
grouped_D
GroupedDataset
==============
{'inputs': {'basepath': None,
'packages': {'couperin_concerts': ["'couperin_concerts.measures' (MuseScoreMeasures)",
"'couperin_concerts.notes' (MuseScoreNotes)",
"'couperin_concerts.expanded' (MuseScoreHarmonies)",
"'couperin_concerts.chords' (MuseScoreChords)",
"'couperin_concerts.metadata' (Metadata)"]}},
'outputs': {'basepath': None, 'packages': {}},
'pipeline': ['ModeGrouper']}
bass_notes = grouped_D.get_feature("bassnotes")
bass_notes.df
| mc | mn | quarterbeats | duration_qb | mc_onset | mn_onset | timesig | staff | voice | volta | label | pedal | chord | numeral | form | figbass | changes | relativeroot | cadence | phraseend | chord_type | chord_tones | added_tones | root | alt_label | globalkey_is_minor | localkey_is_minor | globalkey_mode | localkey_mode | localkey_resolved | localkey_and_mode | root_roman | relativeroot_resolved | effective_localkey | effective_localkey_resolved | effective_localkey_is_minor | pedal_resolved | chord_and_mode | chord_reduced | chord_reduced_and_mode | applied_to_numeral | numeral_or_applied_to_numeral | intervals_over_bass | intervals_over_root | scale_degrees | scale_degrees_and_mode | scale_degrees_major | scale_degrees_minor | bass_degree | bass_degree_and_mode | bass_degree_major | bass_degree_minor | bass_note_over_local_tonic | globalkey | localkey | bass_note | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| mode | corpus | piece | i | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| major | couperin_concerts | c01n01_prelude | 0 | 1 | 0 | 0 | 2.00 | 0 | 1/2 | 4/4 | 1 | 1 | <NA> | G.I{ | <NA> | I | I | <NA> | <NA> | <NA> | <NA> | <NA> | { | M | (0, 4, 1) | () | 0 | <NA> | False | False | major | major | I | I, major | I | NaN | I | I | False | <NA> | I, major | I | I, major | <NA> | I | (M3, P5) | (M3, P5) | (1, 3, 5) | (1, 3, 5), major | (1, 3, 5) | (1, #3, 5) | 1 | 1, major | 1 | 1 | P1 | G | I | 0 |
| 1 | 2 | 1 | 2 | 2.00 | 0 | 0 | 4/4 | 1 | 1 | <NA> | V | <NA> | V | V | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | M | (1, 5, 2) | () | 1 | <NA> | False | False | major | major | I | I, major | V | NaN | I | I | False | <NA> | V, major | V | V, major | <NA> | V | (M3, P5) | (M3, P5) | (5, 7, 2) | (5, 7, 2), major | (5, 7, 2) | (5, #7, 2) | 5 | 5, major | 5 | 5 | P5 | G | I | 1 | |||
| 2 | 2 | 1 | 4 | 0.50 | 1/2 | 1/2 | 4/4 | 1 | 1 | <NA> | I6 | <NA> | I6 | I | <NA> | 6 | <NA> | <NA> | <NA> | <NA> | M | (4, 1, 0) | () | 0 | <NA> | False | False | major | major | I | I, major | I | NaN | I | I | False | <NA> | I6, major | I6 | I6, major | <NA> | I | (m3, m6) | (M3, P5) | (3, 5, 1) | (3, 5, 1), major | (3, 5, 1) | (#3, 5, 1) | 3 | 3, major | 3 | #3 | M3 | G | I | 4 | |||
| 3 | 2 | 1 | 9/2 | 0.50 | 5/8 | 5/8 | 4/4 | 1 | 1 | <NA> | I | <NA> | I | I | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | M | (0, 4, 1) | () | 0 | <NA> | False | False | major | major | I | I, major | I | NaN | I | I | False | <NA> | I, major | I | I, major | <NA> | I | (M3, P5) | (M3, P5) | (1, 3, 5) | (1, 3, 5), major | (1, 3, 5) | (1, #3, 5) | 1 | 1, major | 1 | 1 | P1 | G | I | 0 | |||
| 4 | 2 | 1 | 5 | 0.75 | 3/4 | 3/4 | 4/4 | 1 | 1 | <NA> | V(4) | <NA> | V(4) | V | <NA> | <NA> | 4 | <NA> | <NA> | <NA> | M | (1, 0, 2) | () | 1 | <NA> | False | False | major | major | I | I, major | V | NaN | I | I | False | <NA> | V(4), major | V | V, major | <NA> | V | (P4, P5) | (P4, P5) | (5, 1, 2) | (5, 1, 2), major | (5, 1, 2) | (5, 1, 2) | 5 | 5, major | 5 | 5 | P5 | G | I | 1 | |||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| minor | couperin_concerts | parnasse_07 | 230 | 52 | 52 | 411/2 | 0.25 | 3/8 | 3/8 | 4/4 | 1 | 1 | <NA> | i64 | <NA> | i64 | i | <NA> | 64 | <NA> | <NA> | <NA> | <NA> | m | (1, 0, -3) | () | 0 | <NA> | True | True | minor | minor | i | i, minor | i | NaN | i | i | True | <NA> | i64, minor | i64 | i64, minor | <NA> | i | (P4, m6) | (m3, P5) | (5, 1, 3) | (5, 1, 3), minor | (5, 1, b3) | (5, 1, 3) | 5 | 5, minor | 5 | 5 | P5 | b | i | 1 |
| 231 | 52 | 52 | 823/4 | 0.25 | 7/16 | 7/16 | 4/4 | 1 | 1 | <NA> | iio64 | <NA> | iio64 | ii | o | 64 | <NA> | <NA> | <NA> | <NA> | o | (-4, 2, -1) | () | 2 | <NA> | True | True | minor | minor | i | i, minor | ii | NaN | i | i | True | <NA> | iio64, minor | iio64 | iio64, minor | <NA> | ii | (a4, M6) | (m3, d5) | (6, 2, 4) | (6, 2, 4), minor | (b6, 2, 4) | (6, 2, 4) | 6 | 6, minor | b6 | 6 | m6 | b | i | -4 | |||
| 232 | 52 | 52 | 206 | 1.00 | 1/2 | 1/2 | 4/4 | 1 | 1 | <NA> | i6 | <NA> | i6 | i | <NA> | 6 | <NA> | <NA> | <NA> | <NA> | m | (-3, 1, 0) | () | 0 | <NA> | True | True | minor | minor | i | i, minor | i | NaN | i | i | True | <NA> | i6, minor | i6 | i6, minor | <NA> | i | (M3, M6) | (m3, P5) | (3, 5, 1) | (3, 5, 1), minor | (b3, 5, 1) | (3, 5, 1) | 3 | 3, minor | b3 | 3 | m3 | b | i | -3 | |||
| 233 | 52 | 52 | 207 | 1.00 | 3/4 | 3/4 | 4/4 | 1 | 1 | <NA> | V | <NA> | V | V | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | M | (1, 5, 2) | () | 1 | <NA> | True | True | minor | minor | i | i, minor | V | NaN | i | i | True | <NA> | V, minor | V | V, minor | <NA> | V | (M3, P5) | (M3, P5) | (5, #7, 2) | (5, #7, 2), minor | (5, 7, 2) | (5, #7, 2) | 5 | 5, minor | 5 | 5 | P5 | b | i | 1 | |||
| 234 | 53 | 53 | 208 | 4.00 | 0 | 0 | 4/4 | 1 | 1 | <NA> | i|PAC} | <NA> | i | i | <NA> | <NA> | <NA> | <NA> | PAC | } | m | (0, -3, 1) | () | 0 | <NA> | True | True | minor | minor | i | i, minor | i | NaN | i | i | True | <NA> | i, minor | i | i, minor | <NA> | i | (m3, P5) | (m3, P5) | (1, 3, 5) | (1, 3, 5), minor | (1, b3, 5) | (1, 3, 5) | 1 | 1, minor | 1 | 1 | P1 | b | i | 0 |
8376 rows × 56 columns
bass_notes.plot(
output=make_output_path("piecewise_bass_degrees"), width=1100, height=2500
)
bass_notes.plot_grouped(output=make_output_path("bass_degrees_major_minor"))
Bass degree unigrams#
As expressed by the annotation labels.
labels = D.get_feature("harmonylabels")
df = labels.df
df.head(20)
| mc | mn | quarterbeats | duration_qb | mc_onset | mn_onset | timesig | staff | voice | volta | label | pedal | numeral | form | figbass | changes | relativeroot | cadence | phraseend | chord_type | chord_tones | added_tones | root | bass_note | alt_label | globalkey_is_minor | localkey_is_minor | globalkey_mode | localkey_mode | localkey_resolved | localkey_and_mode | root_roman | relativeroot_resolved | effective_localkey | effective_localkey_resolved | effective_localkey_is_minor | pedal_resolved | chord_and_mode | chord_reduced | chord_reduced_and_mode | applied_to_numeral | numeral_or_applied_to_numeral | intervals_over_bass | intervals_over_root | scale_degrees | scale_degrees_and_mode | scale_degrees_major | scale_degrees_minor | globalkey | localkey | chord | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| corpus | piece | i | |||||||||||||||||||||||||||||||||||||||||||||||||||
| couperin_concerts | c01n01_prelude | 0 | 1 | 0 | 0 | 2.00 | 0 | 1/2 | 4/4 | 1 | 1 | <NA> | G.I{ | <NA> | I | <NA> | <NA> | <NA> | <NA> | <NA> | { | M | (0, 4, 1) | () | 0 | 0 | <NA> | False | False | major | major | I | I, major | I | <NA> | I | I | False | <NA> | I, major | I | I, major | <NA> | I | (M3, P5) | (M3, P5) | (1, 3, 5) | (1, 3, 5), major | (1, 3, 5) | (1, #3, 5) | G | I | I |
| 1 | 2 | 1 | 2 | 2.00 | 0 | 0 | 4/4 | 1 | 1 | <NA> | V | <NA> | V | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | M | (1, 5, 2) | () | 1 | 1 | <NA> | False | False | major | major | I | I, major | V | <NA> | I | I | False | <NA> | V, major | V | V, major | <NA> | V | (M3, P5) | (M3, P5) | (5, 7, 2) | (5, 7, 2), major | (5, 7, 2) | (5, #7, 2) | G | I | V | ||
| 2 | 2 | 1 | 4 | 0.50 | 1/2 | 1/2 | 4/4 | 1 | 1 | <NA> | I6 | <NA> | I | <NA> | 6 | <NA> | <NA> | <NA> | <NA> | M | (4, 1, 0) | () | 0 | 4 | <NA> | False | False | major | major | I | I, major | I | <NA> | I | I | False | <NA> | I6, major | I6 | I6, major | <NA> | I | (m3, m6) | (M3, P5) | (3, 5, 1) | (3, 5, 1), major | (3, 5, 1) | (#3, 5, 1) | G | I | I6 | ||
| 3 | 2 | 1 | 9/2 | 0.50 | 5/8 | 5/8 | 4/4 | 1 | 1 | <NA> | I | <NA> | I | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | M | (0, 4, 1) | () | 0 | 0 | <NA> | False | False | major | major | I | I, major | I | <NA> | I | I | False | <NA> | I, major | I | I, major | <NA> | I | (M3, P5) | (M3, P5) | (1, 3, 5) | (1, 3, 5), major | (1, 3, 5) | (1, #3, 5) | G | I | I | ||
| 4 | 2 | 1 | 5 | 0.75 | 3/4 | 3/4 | 4/4 | 1 | 1 | <NA> | V(4) | <NA> | V | <NA> | <NA> | 4 | <NA> | <NA> | <NA> | M | (1, 0, 2) | () | 1 | 1 | <NA> | False | False | major | major | I | I, major | V | <NA> | I | I | False | <NA> | V(4), major | V | V, major | <NA> | V | (P4, P5) | (P4, P5) | (5, 1, 2) | (5, 1, 2), major | (5, 1, 2) | (5, 1, 2) | G | I | V(4) | ||
| 5 | 2 | 1 | 23/4 | 0.25 | 15/16 | 15/16 | 4/4 | 1 | 1 | <NA> | V | <NA> | V | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | M | (1, 5, 2) | () | 1 | 1 | <NA> | False | False | major | major | I | I, major | V | <NA> | I | I | False | <NA> | V, major | V | V, major | <NA> | V | (M3, P5) | (M3, P5) | (5, 7, 2) | (5, 7, 2), major | (5, 7, 2) | (5, #7, 2) | G | I | V | ||
| 6 | 3 | 2 | 6 | 2.00 | 0 | 0 | 4/4 | 1 | 1 | <NA> | I|IAC} | <NA> | I | <NA> | <NA> | <NA> | <NA> | IAC | } | M | (0, 4, 1) | () | 0 | 0 | <NA> | False | False | major | major | I | I, major | I | <NA> | I | I | False | <NA> | I, major | I | I, major | <NA> | I | (M3, P5) | (M3, P5) | (1, 3, 5) | (1, 3, 5), major | (1, 3, 5) | (1, #3, 5) | G | I | I | ||
| 7 | 3 | 2 | 8 | 1.00 | 1/2 | 1/2 | 4/4 | 1 | 1 | <NA> | vi{ | <NA> | vi | <NA> | <NA> | <NA> | <NA> | <NA> | { | m | (3, 0, 4) | () | 3 | 3 | <NA> | False | False | major | major | I | I, major | vi | <NA> | I | I | False | <NA> | vi, major | vi | vi, major | <NA> | vi | (m3, P5) | (m3, P5) | (6, 1, 3) | (6, 1, 3), major | (6, 1, 3) | (#6, 1, #3) | G | I | vi | ||
| 8 | 3 | 2 | 9 | 1.00 | 3/4 | 3/4 | 4/4 | 1 | 1 | <NA> | I6 | <NA> | I | <NA> | 6 | <NA> | <NA> | <NA> | <NA> | M | (4, 1, 0) | () | 0 | 4 | <NA> | False | False | major | major | I | I, major | I | <NA> | I | I | False | <NA> | I6, major | I6 | I6, major | <NA> | I | (m3, m6) | (M3, P5) | (3, 5, 1) | (3, 5, 1), major | (3, 5, 1) | (#3, 5, 1) | G | I | I6 | ||
| 9 | 4 | 3 | 10 | 1.00 | 0 | 0 | 4/4 | 1 | 1 | <NA> | V6 | <NA> | V | <NA> | 6 | <NA> | <NA> | <NA> | <NA> | M | (5, 2, 1) | () | 1 | 5 | <NA> | False | False | major | major | I | I, major | V | <NA> | I | I | False | <NA> | V6, major | V6 | V6, major | <NA> | V | (m3, m6) | (M3, P5) | (7, 2, 5) | (7, 2, 5), major | (7, 2, 5) | (#7, 2, 5) | G | I | V6 | ||
| 10 | 4 | 3 | 11 | 1.00 | 1/4 | 1/4 | 4/4 | 1 | 1 | <NA> | vi%43/V | <NA> | vi | % | 43 | <NA> | V | <NA> | <NA> | %7 | (-2, 2, 4, 1) | () | 4 | -2 | iii%43 | False | False | major | major | I | I, major | vi/V | V | V/I | V | False | <NA> | vi%43/V, major | vi%43/V | vi%43/V, major | V | V | (M3, a4, M6) | (m3, d5, m7) | (b7, 2, 3, 5) | (b7, 2, 3, 5), major | (b7, 2, 3, 5) | (7, 2, #3, 5) | G | I | vi%43/V | ||
| 11 | 4 | 3 | 12 | 1.00 | 1/2 | 1/2 | 4/4 | 1 | 1 | <NA> | ii7/V | <NA> | ii | <NA> | 7 | <NA> | V | <NA> | <NA> | mm7 | (3, 0, 4, 1) | () | 3 | 3 | <NA> | False | False | major | major | I | I, major | ii/V | V | V/I | V | False | <NA> | ii7/V, major | ii7/V | ii7/V, major | V | V | (m3, P5, m7) | (m3, P5, m7) | (6, 1, 3, 5) | (6, 1, 3, 5), major | (6, 1, 3, 5) | (#6, 1, #3, 5) | G | I | ii7/V | ||
| 12 | 4 | 3 | 13 | 1.00 | 3/4 | 3/4 | 4/4 | 1 | 1 | <NA> | V43/V | <NA> | V | <NA> | 43 | <NA> | V | <NA> | <NA> | Mm7 | (3, 0, 2, 6) | () | 2 | 3 | <NA> | False | False | major | major | I | I, major | V/V | V | V/I | V | False | <NA> | V43/V, major | V43/V | V43/V, major | V | V | (m3, P4, M6) | (M3, P5, m7) | (6, 1, 2, #4) | (6, 1, 2, #4), major | (6, 1, 2, #4) | (#6, 1, 2, #4) | G | I | V43/V | ||
| 13 | 5 | 4 | 14 | 2.00 | 0 | 0 | 4/4 | 1 | 1 | <NA> | V|HC.TEN} | <NA> | V | <NA> | <NA> | <NA> | <NA> | HC.TEN | } | M | (1, 5, 2) | () | 1 | 1 | <NA> | False | False | major | major | I | I, major | V | <NA> | I | I | False | <NA> | V, major | V | V, major | <NA> | V | (M3, P5) | (M3, P5) | (5, 7, 2) | (5, 7, 2), major | (5, 7, 2) | (5, #7, 2) | G | I | V | ||
| 14 | 5 | 4 | 16 | 1.00 | 1/2 | 1/2 | 4/4 | 1 | 1 | <NA> | ii.iio{ | <NA> | ii | o | <NA> | <NA> | <NA> | <NA> | { | o | (2, -1, -4) | () | 2 | 2 | <NA> | False | True | major | minor | ii | ii, major | ii | <NA> | ii | ii | True | <NA> | iio, minor | iio | iio, minor | <NA> | ii | (m3, d5) | (m3, d5) | (2, 4, 6) | (2, 4, 6), minor | (2, 4, b6) | (2, 4, 6) | G | ii | iio | ||
| 15 | 5 | 4 | 17 | 1.00 | 3/4 | 3/4 | 4/4 | 1 | 1 | <NA> | #viio7 | <NA> | #vii | o | 7 | <NA> | <NA> | <NA> | <NA> | o7 | (5, 2, -1, -4) | () | 5 | 5 | <NA> | False | True | major | minor | ii | ii, major | #vii | <NA> | ii | ii | True | <NA> | #viio7, minor | #viio7 | #viio7, minor | <NA> | #vii | (m3, d5, d7) | (m3, d5, d7) | (#7, 2, 4, 6) | (#7, 2, 4, 6), minor | (7, 2, 4, b6) | (#7, 2, 4, 6) | G | ii | #viio7 | ||
| 16 | 6 | 5 | 18 | 1.00 | 0 | 0 | 4/4 | 1 | 1 | <NA> | III+M7(9) | <NA> | III | +M | 7 | 9 | <NA> | <NA> | <NA> | +M7 | (-3, 1, 5, 2) | (-1,) | -3 | -3 | <NA> | False | True | major | minor | ii | ii, major | III | <NA> | ii | ii | True | <NA> | III+M7(9), minor | III+M7 | III+M7, minor | <NA> | III | (M3, a5, M7) | (M3, a5, M7) | (3, 5, #7, 2) | (3, 5, #7, 2), minor | (b3, 5, 7, 2) | (3, 5, #7, 2) | G | ii | III+M7(9) | ||
| 17 | 6 | 5 | 19 | 1.00 | 1/4 | 1/4 | 4/4 | 1 | 1 | <NA> | i6 | <NA> | i | <NA> | 6 | <NA> | <NA> | <NA> | <NA> | m | (-3, 1, 0) | () | 0 | -3 | <NA> | False | True | major | minor | ii | ii, major | i | <NA> | ii | ii | True | <NA> | i6, minor | i6 | i6, minor | <NA> | i | (M3, M6) | (m3, P5) | (3, 5, 1) | (3, 5, 1), minor | (b3, 5, 1) | (3, 5, 1) | G | ii | i6 | ||
| 18 | 6 | 5 | 20 | 1.00 | 1/2 | 1/2 | 4/4 | 1 | 1 | <NA> | ii65 | <NA> | ii | <NA> | 65 | <NA> | <NA> | <NA> | <NA> | mm7 | (-1, 3, 0, 2) | () | 2 | -1 | <NA> | False | True | major | minor | ii | ii, major | ii | <NA> | ii | ii | True | <NA> | ii65, minor | ii65 | ii65, minor | <NA> | ii | (M3, P5, M6) | (m3, P5, m7) | (4, #6, 1, 2) | (4, #6, 1, 2), minor | (4, 6, 1, 2) | (4, #6, 1, 2) | G | ii | ii65 | ||
| 19 | 6 | 5 | 21 | 0.50 | 3/4 | 3/4 | 4/4 | 1 | 1 | <NA> | V64 | <NA> | V | <NA> | 64 | <NA> | <NA> | <NA> | <NA> | M | (2, 1, 5) | () | 1 | 2 | <NA> | False | True | major | minor | ii | ii, major | V | <NA> | ii | ii | True | <NA> | V64, minor | V64 | V64, minor | <NA> | V | (P4, M6) | (M3, P5) | (2, 5, #7) | (2, 5, #7), minor | (2, 5, 7) | (2, 5, #7) | G | ii | V64 |
bd = df.bass_note.value_counts()
print(f"N = {len(df)}")
fig = px.bar(
x=ms3.fifths2sd(bd.index.to_list()),
y=bd.values,
labels=dict(x="Scale degree in relation to major scale", y="count"),
title="Distribution of all bass degrees",
color_discrete_sequence=["grey"] * len(bd),
)
fig.update_xaxes(type="category")
save_figure_as(fig, "bass_degree_unigrams")
fig.show()
N = 8376
localkey_is_major = ~df.localkey_is_minor
print(f"N = {localkey_is_major.sum()}")
bd_maj = df[localkey_is_major].bass_note.value_counts()
fig = px.bar(
bd_maj,
x=ms3.fifths2sd(bd_maj.index.to_list(), minor=False),
y=bd_maj.values,
labels=dict(x="Scale degree in relation to major scale", y="count"),
title="Distribution of bass degrees in major segments",
color_discrete_sequence=["blue"] * len(bd_maj),
)
fig.update_xaxes(type="category")
save_figure_as(fig, "bass_degree_unigrams_major")
fig.show()
N = 4138
print(f"N = {df.localkey_is_minor.sum()}")
bd_min = df[df.localkey_is_minor].bass_note.value_counts()
fig = px.bar(
bd_min,
x=ms3.fifths2sd(bd_min.index.to_list(), minor=True),
y=bd_min.values,
labels=dict(x="Scale degree in relation to minor scale", y="count"),
title="Distribution of bass degrees in minor segments",
color_discrete_sequence=["red"] * len(bd_min),
)
fig.update_xaxes(type="category")
save_figure_as(fig, "bass_degree_unigrams_minor")
fig.show()
N = 4238
Note: When dropping immediate repetitions of the same bass degree (see transition matrices below), minor segments, too, have 1 as the most frequent bass degree. This can be linked to frequent suspensions over bass degree 5.
Intervals between adjacent bass notes#
Preparing the data#
Get localkey segments#
df.groupby(level=0, group_keys=False).localkey.apply(
lambda col: col != col.shift()
).cumsum()
corpus piece i
couperin_concerts c01n01_prelude 0 <NA>
1 0
2 0
3 0
4 0
...
parnasse_07 230 516
231 516
232 516
233 516
234 516
Name: localkey, Length: 8376, dtype: Int64
key_region_groups, key_region2key = make_adjacency_groups(df.localkey, groupby="piece")
df["key_regions"] = key_region_groups
df["bass_degree"] = ms3.transform(df, ms3.fifths2sd, ["bass_note", "localkey_is_minor"])
segment_lengths = df.groupby("key_regions").size()
fig = px.histogram(
segment_lengths,
log_y=True,
labels=dict(value="#labels in a key segment", count="number of key segments"),
)
save_figure_as(fig, "n_labels_per_key_segment_histogram")
fig.show()
# Show all segments of length L
L = 1
selected = segment_lengths[segment_lengths == L].index
df[df.key_regions.isin(selected)]
| mc | mn | quarterbeats | duration_qb | mc_onset | mn_onset | timesig | staff | voice | volta | label | pedal | numeral | form | figbass | changes | relativeroot | cadence | phraseend | chord_type | chord_tones | added_tones | root | bass_note | alt_label | globalkey_is_minor | localkey_is_minor | globalkey_mode | localkey_mode | localkey_resolved | localkey_and_mode | root_roman | relativeroot_resolved | effective_localkey | effective_localkey_resolved | effective_localkey_is_minor | pedal_resolved | chord_and_mode | chord_reduced | chord_reduced_and_mode | applied_to_numeral | numeral_or_applied_to_numeral | intervals_over_bass | intervals_over_root | scale_degrees | scale_degrees_and_mode | scale_degrees_major | scale_degrees_minor | globalkey | localkey | chord | key_regions | bass_degree | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| corpus | piece | i | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| couperin_concerts | parnasse_06 | 33 | 13 | 13 | 37/2 | 6.5 | 1/8 | 1/8 | 3/8 | 1 | 1 | <NA> | iii.i | <NA> | i | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | m | (0, -3, 1) | () | 0 | 0 | <NA> | False | True | major | minor | iii | iii, major | i | <NA> | iii | iii | True | <NA> | i, minor | i | i, minor | <NA> | i | (m3, P5) | (m3, P5) | (1, 3, 5) | (1, 3, 5), minor | (1, b3, 5) | (1, 3, 5) | D | iii | i | 551 | 1 |
Delete @none labels
This creates progressions between the label before and after the @none label that might not actually be perceived
as transitions!
df = utils.remove_none_labels(df)
Length before: 8376
There are 0 @none labels which we are going to delete.
Length after: 8376
Delete non-chord labels (typically, phrase labels)
df = utils.remove_non_chord_labels(df)
Length before: 8376
There are 0 non-chord labels which we are going to delete:
Series([], Name: count, dtype: Int64)
Length after: 8376
Get bass degree progressions & intervals#
All scale degrees are expressed as fifth-intervals to the local tonic:
fifths-interval |
interval |
|---|---|
-3 |
m3 |
-2 |
m7 |
-1 |
P4 |
0 |
local tonic |
1 |
P5 |
2 |
M2 |
3 |
M6 |
bd_series = {seg: bn for seg, bn in df.groupby("key_regions").bass_note}
bd_intervals = {seg: bd - bd.shift() for seg, bd in bd_series.items()}
df["bass_interval"] = df.groupby("key_regions", group_keys=False).bass_note.apply(
lambda bd: bd.shift(-1) - bd
)
print("Example output for the intervals of the first key segment:")
df.loc[df.key_regions == 1, ["bass_note", "bass_interval"]]
Example output for the intervals of the first key segment:
| bass_note | bass_interval | |||
|---|---|---|---|---|
| corpus | piece | i | ||
| couperin_concerts | c01n01_prelude | 0 | 0 | 1 |
| 1 | 1 | 3 | ||
| 2 | 4 | -4 | ||
| 3 | 0 | 1 | ||
| 4 | 1 | 0 | ||
| 5 | 1 | -1 | ||
| 6 | 0 | 3 | ||
| 7 | 3 | 1 | ||
| 8 | 4 | 1 | ||
| 9 | 5 | -7 | ||
| 10 | -2 | 5 | ||
| 11 | 3 | 0 | ||
| 12 | 3 | -2 | ||
| 13 | 1 | <NA> |
Count bass intervals#
interval_counter = Counter()
for S in bd_intervals.values():
interval_counter.update(S.dropna())
interval_counter
Counter({-1: 1422,
0: 917,
2: 852,
-2: 788,
-5: 725,
3: 704,
1: 599,
5: 587,
-4: 549,
4: 286,
-3: 207,
6: 53,
8: 49,
7: 25,
-8: 22,
-7: 14,
-6: 7,
9: 2,
-9: 2})
bar_data = pd.Series(interval_counter).sort_values(ascending=False)
fig = px.bar(
x=ms3.fifths2iv(bar_data.index.to_list()),
y=bar_data.values,
labels=dict(x="Interval between adjacent bass notes", y="count"),
title="Distribution of all bass intervals (within the same localkey)",
color_discrete_sequence=["grey"] * len(bd),
)
fig.update_xaxes(type="category")
save_figure_as(fig, "bass_progression_intervals_within_all_key_segments_sorted_bars")
fig.show()
**
px.bar(
x=interval_counter.keys(),
y=interval_counter.values(),
labels=dict(x="interval in fifths", y="count"),
title="Orderd on the line of fifths",
)
iv_order = [
-6,
1,
8,
-11,
-4,
3,
10,
-9,
-2,
5,
12,
-7,
0,
7,
-5,
2,
9,
-10,
-3,
4,
11,
-8,
-1,
6,
] # do not occur: -11, -10, 11
iv_counter = {
ms3.fifths2iv(i, True): interval_counter[i]
for i in iv_order
if i in interval_counter
}
px.bar(
x=iv_counter.keys(),
y=iv_counter.values(),
labels=dict(x="interval", y="count"),
title="Ordered by base " "interval",
)
iv_order = [
12,
10,
-9,
-6,
-7,
8,
-4,
5,
1,
3,
-2,
0,
-1,
2,
-5,
4,
-3,
6,
7,
-8,
9,
] # do not occur: -11, -10, 11
iv_counter = {
ms3.fifths2iv(i): interval_counter[i] for i in iv_order if i in interval_counter
}
px.bar(
x=iv_counter.keys(),
y=iv_counter.values(),
labels=dict(x="interval", y="count"),
title="Ordered around the unison",
)
px.bar(
x=sorted(iv_counter.keys(), key=lambda k: iv_counter[k], reverse=True),
y=sorted(iv_counter.values(), reverse=True),
labels=dict(x="interval", y="count"),
title="Descending frequency",
)
Checking rare intervals#
occurrences of -9 (-A2)
c02n01_preludem. 12:ii%was corrected toiii%
The other two were correct:
c07n05_gavotem. 27: progressionV65 VIM7in minorc03n05_gavottem. 22: progressionV65 ii%43(in minor)
# see all key regions containing a certain interval in the bass
bass_interval = -9
selected = df.loc[df.bass_interval == bass_interval].key_regions.unique()
df.loc[
df.key_regions.isin(selected), ["mc", "mn", "chord", "bass_degree", "bass_interval"]
]
| mc | mn | chord | bass_degree | bass_interval | |||
|---|---|---|---|---|---|---|---|
| corpus | piece | i | |||||
| couperin_concerts | c03n05_gavotte | 52 | 19 | 16 | VII6 | 2 | 2 |
| 53 | 19 | 16 | V65/IV | #3 | -5 | ||
| 54 | 19 | 16 | IV | 4 | 3 | ||
| 55 | 19 | 16 | V43 | 2 | -5 | ||
| 56 | 20 | 17 | i6 | 3 | 2 | ||
| 57 | 20 | 17 | ii%65 | 4 | 2 | ||
| 58 | 20 | 17 | V | 5 | 4 | ||
| 59 | 21 | 18 | V65 | #7 | -4 | ||
| 60 | 21 | 18 | V7 | 5 | -1 | ||
| 61 | 21 | 18 | i | 1 | 1 | ||
| 62 | 22 | 19 | V | 5 | -1 | ||
| 63 | 22 | 19 | i | 1 | 2 | ||
| 64 | 23 | 20 | V43 | 2 | -5 | ||
| 65 | 23 | 20 | i6 | 3 | 8 | ||
| 66 | 23 | 20 | V65 | #7 | -5 | ||
| 67 | 24 | 21 | i | 1 | -3 | ||
| 68 | 24 | 21 | i6 | 3 | 8 | ||
| 69 | 24 | 21 | V65 | #7 | -5 | ||
| 70 | 25 | 22 | i | 1 | 2 | ||
| 71 | 25 | 22 | V43 | 2 | -5 | ||
| 72 | 25 | 22 | i6 | 3 | 8 | ||
| 73 | 25 | 22 | V65 | #7 | -9 | ||
| 74 | 25 | 22 | ii%43 | 6 | 5 | ||
| 75 | 26 | 23 | i64 | 5 | -4 | ||
| 76 | 26 | 23 | i6 | 3 | 5 | ||
| 77 | 26 | 23 | V43 | 2 | -5 | ||
| 78 | 26 | 23 | i6 | 3 | 8 | ||
| 79 | 26 | 23 | V65 | #7 | -5 | ||
| 80 | 27 | 24 | i | 1 | -3 | ||
| 81 | 27 | 24 | i6 | 3 | 2 | ||
| 82 | 27 | 24 | iv | 4 | 2 | ||
| 83 | 27 | 24 | V | 5 | -1 | ||
| 84 | 28 | 25 | i | 1 | <NA> | ||
| c07n05_gavote | 33 | 22 | 20 | iv | 4 | 3 | |
| 34 | 23 | 21 | iio | 2 | 3 | ||
| 35 | 23 | 21 | V65 | #7 | -4 | ||
| 36 | 23 | 21 | V7 | 5 | -1 | ||
| 37 | 24 | 22 | i | 1 | 1 | ||
| 38 | 24 | 22 | V | 5 | -1 | ||
| 39 | 24 | 22 | i | 1 | -4 | ||
| 40 | 25 | 23 | iv6 | 6 | 4 | ||
| 41 | 26 | 24 | i | 1 | 1 | ||
| 42 | 27 | 25 | V | 5 | -1 | ||
| 43 | 27 | 25 | i | 1 | -4 | ||
| 44 | 27 | 25 | VI | 6 | 3 | ||
| 45 | 27 | 25 | ii%65 | 4 | 2 | ||
| 46 | 28 | 26 | V | 5 | -2 | ||
| 47 | 28 | 26 | V2 | 4 | -2 | ||
| 48 | 28 | 26 | i6 | 3 | 3 | ||
| 49 | 28 | 26 | i7 | 1 | -1 | ||
| 50 | 28 | 26 | iv | 4 | 3 | ||
| 51 | 28 | 26 | iio | 2 | 3 | ||
| 52 | 29 | 27 | V65 | #7 | -9 | ||
| 53 | 29 | 27 | VIM7 | 6 | 5 | ||
| 54 | 29 | 27 | V | 5 | 0 | ||
| 55 | 29 | 27 | V7 | 5 | -1 | ||
| 56 | 30 | 28 | i | 1 | <NA> |
Inspecting stepwise bass movement#
Add column with bass interval in semitones.
It’s called bass_interval_pc as in “pitch class”
pc_ivs = ms3.transform(df, ms3.fifths2pc, ["bass_interval"])
df["bass_interval_pc"] = pc_ivs.where(pc_ivs <= 6, pc_ivs % -6)
df[["mc", "mn", "chord", "bass_degree", "bass_interval", "bass_interval_pc"]].head(15)
| mc | mn | chord | bass_degree | bass_interval | bass_interval_pc | |||
|---|---|---|---|---|---|---|---|---|
| corpus | piece | i | ||||||
| couperin_concerts | c01n01_prelude | 0 | 1 | 0 | I | 1 | 1 | -5 |
| 1 | 2 | 1 | V | 5 | 3 | -3 | ||
| 2 | 2 | 1 | I6 | 3 | -4 | -4 | ||
| 3 | 2 | 1 | I | 1 | 1 | -5 | ||
| 4 | 2 | 1 | V(4) | 5 | 0 | 0 | ||
| 5 | 2 | 1 | V | 5 | -1 | 5 | ||
| 6 | 3 | 2 | I | 1 | 3 | -3 | ||
| 7 | 3 | 2 | vi | 6 | 1 | -5 | ||
| 8 | 3 | 2 | I6 | 3 | 1 | -5 | ||
| 9 | 4 | 3 | V6 | 7 | -7 | -1 | ||
| 10 | 4 | 3 | vi%43/V | b7 | 5 | -1 | ||
| 11 | 4 | 3 | ii7/V | 6 | 0 | 0 | ||
| 12 | 4 | 3 | V43/V | 6 | -2 | -2 | ||
| 13 | 5 | 4 | V | 5 | <NA> | <NA> | ||
| 14 | 5 | 4 | iio | 2 | 3 | -3 |
Create key region summary#
With one row per key region and the following columns
column |
what it contains |
|---|---|
globalkey |
the global key of the segment |
localkey |
the local key of the segment |
length |
number of labels |
length_norepeat |
number of labels without immediate repetitions |
n_stepwise |
number of stepwise bass progressions |
%_stepwise |
percentage of stepwise progressions (based on length_norepeat) |
n_ascending |
number of stepwise ascending bass progressions |
n_descending |
number of stepwise descending bass progressions |
bd |
full sequence of bass degrees |
stepwise_bd |
all sequences of consecutive stepwise bass progressions |
stepwise_chords |
the corresponding chord sequences |
ascending_bd |
the subset of ascending bass progressions |
ascending_chords |
the corresponding chord sequences |
descending_bd |
the subset of descending bass progressions |
descending_chords |
the corresponding chord sequences |
ixa |
index of the segment’s first row |
ixb |
index of the segment’s last row |
key_regions = utils.make_key_region_summary_table(df, "key_regions")
key_regions.head(10)
| globalkey | localkey | length | length_norepeat | n_stepwise | %_stepwise | n_ascending | n_descending | bd | stepwise_bd | stepwise_chords | ascending_bd | ascending_chords | descending_bd | descending_chords | ixa | ixb | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| key_regions | |||||||||||||||||
| 1 | G | I | 14 | 12 | 3 | 25.0 | 0 | 3 | 1 5 3 1 5 1 6 3 7 b7 6 5 | [7 b7 6 6] | [V6 vi%43/V ii7/V V43/V] | [] | [] | [7 b7 6 6] | [V6 vi%43/V ii7/V V43/V] | (couperin_concerts, c01n01_prelude, 0) | (couperin_concerts, c01n01_prelude, 13) |
| 2 | G | ii | 8 | 7 | 1 | 14.3 | 1 | 0 | 2 #7 3 4 2 5 1 | [3 3 4] | [III+M7(9) i6 ii65] | [3 3 4] | [III+M7(9) i6 ii65] | [] | [] | (couperin_concerts, c01n01_prelude, 14) | (couperin_concerts, c01n01_prelude, 21) |
| 3 | G | V | 13 | 10 | 7 | 70.0 | 2 | 5 | 5 4 3 2 1 4 3 4 5 1 | [5 5 4 3 2 1, 4 3 4 5 5 5] | [V I64 V2 I6 V43 vi6, V2 I6 ii65 V(64) V V7] | [3 4 5 5 5] | [I6 ii65 V(64) V V7] | [5 5 4 3 2 1, 4 3] | [V I64 V2 I6 V43 vi6, V2 I6] | (couperin_concerts, c01n01_prelude, 22) | (couperin_concerts, c01n01_prelude, 34) |
| 4 | G | IV | 6 | 4 | 1 | 25.0 | 0 | 1 | 4 3 5 1 | [4 4 3] | [ii6 V2 I6] | [] | [] | [4 4 3] | [ii6 V2 I6] | (couperin_concerts, c01n01_prelude, 35) | (couperin_concerts, c01n01_prelude, 40) |
| 5 | G | V | 7 | 7 | 3 | 42.9 | 1 | 2 | 5 3 2 1 5 7 1 | [3 2 1, 7] | [I6 V43 I, V65] | [7] | [V65] | [3 2 1] | [I6 V43 I] | (couperin_concerts, c01n01_prelude, 41) | (couperin_concerts, c01n01_prelude, 47) |
| 6 | G | I | 45 | 36 | 19 | 52.8 | 9 | 10 | 7 1 2 7 1 6 5 4 3 4 2 1 5 3 2 1 4 3 5 1 6 5 4 ... | [7 1 2, 7 1, 6 5 4 3 4, 2 1, 3 2 1, 4 4 4 3, 6... | [V65 I V43, V6 I, vi I64 viio64 I6 IV, V43 I, ... | [7 1 2, 7 1, 3 4, 4 #4 5 6 7 1] | [V65 I V43, V6 I, I6 IV, IVM7 V65/V V vi7 V65 I] | [6 5 4 3, 2 1, 3 2 1, 4 4 4 3, 6 6 5 5 4, 4 4 ... | [vi I64 viio64 I6, V43 I, I6 V43 I, IVM7 ii65 ... | (couperin_concerts, c01n01_prelude, 48) | (couperin_concerts, c01n01_prelude, 93) |
| 7 | G | I | 15 | 11 | 4 | 36.4 | 2 | 2 | 1 7 5 6 5 1 5 1 2 5 1 | [1 7, 5 6 6 5, 1 1 2] | [I V6, V IV6(2) IV6 V7, I I ii7] | [5 6 6, 1 1 2] | [V IV6(2) IV6, I I ii7] | [1 7, 6 6 5] | [I V6, IV6(2) IV6 V7] | (couperin_concerts, c01n02_allemande, 0) | (couperin_concerts, c01n02_allemande, 14) |
| 8 | G | V | 22 | 22 | 13 | 59.1 | 9 | 4 | 3 1 5 7 1 7 1 5 6 4 5 1 7 1 7 1 7 1 3 4 5 1 | [7 1 7 1, 5 6, 4 5, 1 7 1 7 1 7 1, 3 4 5] | [V6 I V6 I, V7 vi, IVM7 V, I V65 I V65 I V65 I... | [7 1, 7 1, 5 6, 4 5, 7 1, 7 1, 7 1, 3 4 5] | [V6 I, V6 I, V7 vi, IVM7 V, V65 I, V65 I, V65 ... | [1 7, 1 7, 1 7, 1 7] | [I V6, I V65, I V65, I V65] | (couperin_concerts, c01n02_allemande, 15) | (couperin_concerts, c01n02_allemande, 37) |
| 9 | G | I | 3 | 3 | 1 | 33.3 | 1 | 0 | 5 3 4 | [3] | [I6] | [3] | [I6] | [] | [] | (couperin_concerts, c01n02_allemande, 38) | (couperin_concerts, c01n02_allemande, 40) |
| 10 | G | vi | 12 | 11 | 6 | 54.5 | 4 | 2 | 4 5 3 1 4 3 4 3 4 5 1 | [4 5, 4 3 4 3 4 5 5] | [ii%65 V, V2 i6 V2 i6 ii65 V(64) V] | [4 5, 3 4, 3 4 5 5] | [ii%65 V, i6 V2, i6 ii65 V(64) V] | [4 3, 4 3] | [V2 i6, V2 i6] | (couperin_concerts, c01n02_allemande, 41) | (couperin_concerts, c01n02_allemande, 52) |
Store to file key_regions.tsv for easier inspection.
key_regions.to_csv(os.path.join(RESULTS_PATH, "key_regions.tsv"), sep="\t")
print(
f"{key_regions.n_stepwise.sum() / key_regions.length_norepeat.sum():.1%} of all bass movements are stepwise."
)
40.1% of all bass movements are stepwise.
def remove_immediate_repetitions(s):
res = []
last = ""
for word in s.split():
if word != last:
res.append(word)
last = word
return " ".join(res)
minor_selector = key_regions.localkey.str.islower()
minor_regions = key_regions[minor_selector]
major_regions = key_regions[~minor_selector]
All stepwise ascending bass progressions in minor#
ascending_minor = defaultdict(list)
for bd, chord in zip(
minor_regions.ascending_bd.sum(), minor_regions.ascending_chords.sum()
):
ascending_minor[remove_immediate_repetitions(bd)].append(chord)
ascending_minor_counts = Counter({k: len(v) for k, v in ascending_minor.items()})
utils.prettify_counts(ascending_minor_counts)
N = 604
| count | % | |
|---|---|---|
| progression | ||
| 4 5 | 143 | 23.68 |
| #7 1 | 113 | 18.71 |
| 3 4 5 | 40 | 6.62 |
| 2 3 | 40 | 6.62 |
| 5 6 | 33 | 5.46 |
| 3 4 | 32 | 5.30 |
| #3 4 | 26 | 4.30 |
| 1 2 | 18 | 2.98 |
| 4 5 6 | 17 | 2.81 |
| #7 | 13 | 2.15 |
| 1 2 3 | 10 | 1.66 |
| 2 3 4 5 | 9 | 1.49 |
| #3 4 5 6 | 7 | 1.16 |
| 5 #6 #7 1 | 7 | 1.16 |
| #7 1 2 3 | 7 | 1.16 |
| 5 | 7 | 1.16 |
| 3 4 5 6 | 7 | 1.16 |
| #6 #7 1 | 6 | 0.99 |
| 7 1 | 5 | 0.83 |
| 6 7 | 5 | 0.83 |
| 2 3 4 5 6 | 4 | 0.66 |
| 5 #6 #7 | 3 | 0.50 |
| #3 4 5 | 3 | 0.50 |
| 2 #3 4 | 3 | 0.50 |
| 2 3 4 | 3 | 0.50 |
| 1 2 3 4 5 | 3 | 0.50 |
| #3 | 3 | 0.50 |
| #7 1 2 3 4 5 | 3 | 0.50 |
| #7 1 2 3 4 | 2 | 0.33 |
| 2 | 2 | 0.33 |
| 5 #6 | 2 | 0.33 |
| #6 #7 | 2 | 0.33 |
| 3 4 5 #6 #7 1 | 2 | 0.33 |
| #4 5 | 2 | 0.33 |
| #7 1 2 | 2 | 0.33 |
| #3 4 5 #6 | 1 | 0.17 |
| 4 5 6 #6 7 #7 1 | 1 | 0.17 |
| 3 4 #4 5 6 | 1 | 0.17 |
| 4 #4 5 6 | 1 | 0.17 |
| 3 #3 4 5 | 1 | 0.17 |
| 3 4 5 #6 #7 | 1 | 0.17 |
| 3 | 1 | 0.17 |
| 4 5 #6 #7 | 1 | 0.17 |
| 1 2 #3 4 | 1 | 0.17 |
| 4 | 1 | 0.17 |
| #3 4 #4 5 6 | 1 | 0.17 |
| 1 2 3 #3 4 | 1 | 0.17 |
| 4 #4 5 | 1 | 0.17 |
| 4 5 6 #6 7 #7 | 1 | 0.17 |
| 5 #6 #7 1 2 | 1 | 0.17 |
| #6 | 1 | 0.17 |
| 4 5 #6 | 1 | 0.17 |
| 2 #3 | 1 | 0.17 |
| 5 6 #6 7 #7 1 | 1 | 0.17 |
| 5 #6 #7 1 2 #3 4 | 1 | 0.17 |
show_progression = "3 4 5"
chords_3_4_5 = Counter(ascending_minor[show_progression])
utils.prettify_counts(chords_3_4_5)
N = 40
| count | % | |
|---|---|---|
| progression | ||
| i6 ii%65 V | 8 | 20.0 |
| i6 ii%65 V V7 | 7 | 17.5 |
| i6 ii%65 V(4) V | 7 | 17.5 |
| i6 ii%65 V(64) V | 5 | 12.5 |
| i6 ii65 V V7 | 2 | 5.0 |
| i6 ii65 V(64) V | 1 | 2.5 |
| i6 ii%65 V(64) V7 | 1 | 2.5 |
| i6 iv V | 1 | 2.5 |
| i6 IV iio6 V | 1 | 2.5 |
| i6 IV7 V | 1 | 2.5 |
| i6 iv7 ii%65 V | 1 | 2.5 |
| i6 iv ii6 V | 1 | 2.5 |
| i6 iv7(9) V(4) V | 1 | 2.5 |
| i6 ii%65 V(64) | 1 | 2.5 |
| III ii%65 V | 1 | 2.5 |
| i6 IV7(9) ii6 V7 | 1 | 2.5 |
All stepwise ascending bass progressions in major#
ascending_major = defaultdict(list)
for bd, chord in zip(
major_regions.ascending_bd.sum(), major_regions.ascending_chords.sum()
):
ascending_major[remove_immediate_repetitions(bd)].append(chord)
ascending_major_counts = Counter({k: len(v) for k, v in ascending_major.items()})
utils.prettify_counts(ascending_major_counts)
N = 524
| count | % | |
|---|---|---|
| progression | ||
| 7 1 | 115 | 21.95 |
| 4 5 | 101 | 19.27 |
| 3 4 | 60 | 11.45 |
| 3 4 5 | 34 | 6.49 |
| 5 6 | 32 | 6.11 |
| 6 7 1 | 30 | 5.73 |
| 1 2 | 22 | 4.20 |
| 2 3 | 16 | 3.05 |
| 7 | 15 | 2.86 |
| 1 2 3 | 11 | 2.10 |
| 5 6 7 | 9 | 1.72 |
| 5 6 7 1 | 9 | 1.72 |
| #4 5 | 8 | 1.53 |
| 3 4 5 6 | 7 | 1.34 |
| 3 | 6 | 1.15 |
| 6 7 | 5 | 0.95 |
| 3 4 #4 5 | 4 | 0.76 |
| 7 1 2 | 3 | 0.57 |
| 4 #4 5 | 3 | 0.57 |
| 2 3 4 5 | 3 | 0.57 |
| 3 4 5 6 7 1 | 3 | 0.57 |
| 1 2 3 4 5 | 3 | 0.57 |
| 4 5 6 | 2 | 0.38 |
| 2 3 4 | 2 | 0.38 |
| 4 5 6 7 1 | 2 | 0.38 |
| 1 2 3 4 | 2 | 0.38 |
| 4 5 6 7 | 2 | 0.38 |
| 3 4 #4 5 6 7 1 | 2 | 0.38 |
| 4 #4 5 6 7 1 | 1 | 0.19 |
| 7 1 2 3 | 1 | 0.19 |
| #1 2 | 1 | 0.19 |
| 2 | 1 | 0.19 |
| 5 #5 6 | 1 | 0.19 |
| 3 #4 | 1 | 0.19 |
| 3 4 5 6 7 | 1 | 0.19 |
| 1 2 3 4 5 6 7 1 | 1 | 0.19 |
| 5 #5 6 7 1 | 1 | 0.19 |
| 7 #1 2 | 1 | 0.19 |
| 1 #1 2 | 1 | 0.19 |
| 7 #1 | 1 | 0.19 |
| 2 3 #4 5 6 7 1 | 1 | 0.19 |
show_progression = "6 7 1"
chords_6_7_1 = Counter(ascending_major[show_progression])
utils.prettify_counts(chords_6_7_1)
N = 30
| count | % | |
|---|---|---|
| progression | ||
| IV6 V65 I | 8 | 26.67 |
| IV6 V65 I(4) I | 4 | 13.33 |
| vi V65 I | 2 | 6.67 |
| IV6 V65 I ii2 | 2 | 6.67 |
| vi V65 I(4) I | 1 | 3.33 |
| IV6(2) IV6 V65 I | 1 | 3.33 |
| vi7 IV6 V65 I | 1 | 3.33 |
| IV6 V6 I IV64 | 1 | 3.33 |
| vi IV6 V65 I | 1 | 3.33 |
| vi7 IV6 vii%7 V65 I | 1 | 3.33 |
| IV6 V65 I(4) | 1 | 3.33 |
| IVM65 V65 I(9) | 1 | 3.33 |
| vi7 V65 I | 1 | 3.33 |
| IV6 viio I | 1 | 3.33 |
| IVM65 V65 I(9) I | 1 | 3.33 |
| IV65 V65 I(9) I | 1 | 3.33 |
| vi7 V65 I(94) | 1 | 3.33 |
| IV6 V65(9) V65 I | 1 | 3.33 |
All stepwise descending bass progressions in minor#
descending_minor = defaultdict(list)
for bd, chord in zip(
minor_regions.descending_bd.sum(), minor_regions.descending_chords.sum()
):
descending_minor[remove_immediate_repetitions(bd)].append(chord)
descending_minor_counts = Counter({k: len(v) for k, v in descending_minor.items()})
utils.prettify_counts(descending_minor_counts)
N = 400
| count | % | |
|---|---|---|
| progression | ||
| 1 #7 | 49 | 12.25 |
| 6 5 | 39 | 9.75 |
| 4 3 | 36 | 9.00 |
| 3 2 | 34 | 8.50 |
| 3 2 1 | 24 | 6.00 |
| 5 4 3 | 21 | 5.25 |
| 1 7 6 | 18 | 4.50 |
| 1 7 6 5 | 16 | 4.00 |
| 5 4 | 15 | 3.75 |
| 2 1 | 14 | 3.50 |
| 3 2 1 #7 | 12 | 3.00 |
| 4 3 2 1 | 11 | 2.75 |
| 1 7 | 10 | 2.50 |
| 5 4 3 2 | 9 | 2.25 |
| 6 5 4 | 8 | 2.00 |
| 2 1 #7 | 7 | 1.75 |
| 5 4 3 2 1 | 7 | 1.75 |
| 4 3 2 1 #7 | 6 | 1.50 |
| 6 | 6 | 1.50 |
| 4 3 2 | 6 | 1.50 |
| 6 5 4 3 | 5 | 1.25 |
| 5 4 3 2 1 #7 | 5 | 1.25 |
| 6 5 4 3 2 1 | 5 | 1.25 |
| 6 5 4 3 2 | 4 | 1.00 |
| 4 #3 | 3 | 0.75 |
| 1 7 6 5 4 3 | 3 | 0.75 |
| #6 5 | 2 | 0.50 |
| 1 7 6 5 4 3 2 | 2 | 0.50 |
| 1 | 2 | 0.50 |
| 1 7 #6 5 | 2 | 0.50 |
| 2 | 2 | 0.50 |
| 6 5 4 3 2 1 #7 | 2 | 0.50 |
| #7 7 6 5 4 | 1 | 0.25 |
| 5 | 1 | 0.25 |
| 5 #4 | 1 | 0.25 |
| #6 | 1 | 0.25 |
| 6 5 4 #3 | 1 | 0.25 |
| 7 6 5 4 3 | 1 | 0.25 |
| #6 6 5 | 1 | 0.25 |
| 2 1 #7 7 #6 6 | 1 | 0.25 |
| #7 7 6 | 1 | 0.25 |
| 5 #4 4 3 | 1 | 0.25 |
| 5 4 #3 | 1 | 0.25 |
| 7 6 5 4 | 1 | 0.25 |
| 1 #7 7 6 5 | 1 | 0.25 |
| 7 6 | 1 | 0.25 |
| 4 3 2 1 7 6 5 | 1 | 0.25 |
show_progression = "3 2 1"
chords_3_2_1 = Counter(descending_minor[show_progression])
utils.prettify_counts(chords_3_2_1)
N = 24
| count | % | |
|---|---|---|
| progression | ||
| i6 V43 i | 17 | 70.83 |
| III+7 i6 V43 i | 1 | 4.17 |
| III+ i6 V43 i | 1 | 4.17 |
| IV2 V43 i | 1 | 4.17 |
| i6 ii%7 V43 i i | 1 | 4.17 |
| #vio64 #viio6 i | 1 | 4.17 |
| III+ #vio64 #viio6 i | 1 | 4.17 |
| i6 #viio6 i | 1 | 4.17 |
All stepwise descending bass progressions in major#
descending_major = defaultdict(list)
for bd, chord in zip(
major_regions.descending_bd.sum(), major_regions.descending_chords.sum()
):
descending_major[remove_immediate_repetitions(bd)].append(chord)
descending_major_counts = Counter({k: len(v) for k, v in descending_major.items()})
utils.prettify_counts(descending_major_counts)
N = 354
| count | % | |
|---|---|---|
| progression | ||
| 1 7 | 67 | 18.93 |
| 4 3 | 44 | 12.43 |
| 6 5 | 31 | 8.76 |
| 2 1 | 29 | 8.19 |
| 5 4 3 | 20 | 5.65 |
| 3 2 1 | 19 | 5.37 |
| 1 7 6 5 | 17 | 4.80 |
| 4 3 2 1 | 16 | 4.52 |
| 4 3 2 | 14 | 3.95 |
| 1 7 6 | 12 | 3.39 |
| 3 2 | 12 | 3.39 |
| 3 2 1 7 | 9 | 2.54 |
| 5 4 3 2 1 | 5 | 1.41 |
| 6 5 4 | 5 | 1.41 |
| 5 4 3 2 | 5 | 1.41 |
| 5 4 | 5 | 1.41 |
| b7 6 | 5 | 1.41 |
| 6 5 4 3 | 3 | 0.85 |
| 1 7 b7 6 | 3 | 0.85 |
| 2 1 7 | 3 | 0.85 |
| 1 | 3 | 0.85 |
| 7 6 | 3 | 0.85 |
| 7 b7 6 | 2 | 0.56 |
| 6 | 2 | 0.56 |
| 1 7 6 5 4 3 | 2 | 0.56 |
| 1 b7 6 | 2 | 0.56 |
| 6 5 4 3 2 | 2 | 0.56 |
| 4 3 2 1 7 | 2 | 0.56 |
| 1 b7 6 5 4 | 1 | 0.28 |
| 7 6 5 #4 | 1 | 0.28 |
| 4 3 2 1 7 6 5 | 1 | 0.28 |
| 1 7 6 5 4 3 2 1 | 1 | 0.28 |
| 5 4 3 2 1 7 b7 6 | 1 | 0.28 |
| 5 4 3 2 1 7 6 | 1 | 0.28 |
| 1 7 b7 | 1 | 0.28 |
| 2 1 7 6 5 | 1 | 0.28 |
| 7 6 5 | 1 | 0.28 |
| 3 2 1 7 6 5 4 3 | 1 | 0.28 |
| 2 | 1 | 0.28 |
| 7 6 5 4 3 2 1 | 1 | 0.28 |
show_progression = "5 4 3"
chords_5_4_3 = Counter(descending_major[show_progression])
utils.prettify_counts(chords_5_4_3)
N = 20
| count | % | |
|---|---|---|
| progression | ||
| V V2 I6 | 15 | 75.0 |
| V V2 V65/IV | 1 | 5.0 |
| I64 V2 I6 | 1 | 5.0 |
| I64 V I64 ii6(2) ii6 I6(2) I6 | 1 | 5.0 |
| I64 V ii6 I6 | 1 | 5.0 |
| V V2 iii | 1 | 5.0 |
Transitions between bass degrees#
full_grams = {
i: S[(S != S.shift()).fillna(True)].to_list() for i, S in bd_series.items()
}
print(bd_series[1])
full_grams[1]
corpus piece i
couperin_concerts c01n01_prelude 0 0
1 1
2 4
3 0
4 1
5 1
6 0
7 3
8 4
9 5
10 -2
11 3
12 3
13 1
Name: bass_note, dtype: Int64
[0, 1, 4, 0, 1, 0, 3, 4, 5, -2, 3, 1]
minor_region_selector = key_regions.localkey.str.islower()
minor_regions = key_regions[minor_region_selector].localkey.to_dict()
major_regions = key_regions[~minor_region_selector].localkey.to_dict()
full_grams_minor = [ms3.fifths2sd(full_grams[i], True) + ["∅"] for i in minor_regions]
full_grams_major = [ms3.fifths2sd(full_grams[i], False) + ["∅"] for i in major_regions]
utils.plot_transition_heatmaps(full_grams_major, full_grams_minor)
save_pdf_path = os.path.join(
RESULTS_PATH, f"bass_degree_bigrams{utils.DEFAULT_OUTPUT_FORMAT}"
)
plt.savefig(save_pdf_path, dpi=400)
plt.show()
utils.plot_transition_heatmaps(
full_grams_major, full_grams_minor, sort_scale_degrees=True
)
save_pdf_path = os.path.join(
RESULTS_PATH, f"bass_degree_bigrams_scale_order{utils.DEFAULT_OUTPUT_FORMAT}"
)
plt.savefig(save_pdf_path, dpi=400)
plt.show()
Most frequent 2-grams#
Select number of first k transitions to display:
k = 25
Major#
utils.sorted_gram_counts(full_grams_major, 2)
N = 3077
| count | % | |
|---|---|---|
| progression | ||
| (5, 1) | 433 | 14.07 |
| (1, 5) | 242 | 7.86 |
| (1, ∅) | 206 | 6.69 |
| (7, 1) | 187 | 6.08 |
| (4, 5) | 159 | 5.17 |
| (1, 4) | 146 | 4.74 |
| (5, 3) | 138 | 4.48 |
| (3, 4) | 128 | 4.16 |
| (1, 7) | 126 | 4.09 |
| (4, 3) | 119 | 3.87 |
| (3, 1) | 107 | 3.48 |
| (2, 1) | 100 | 3.25 |
| (2, 5) | 97 | 3.15 |
| (3, 2) | 90 | 2.92 |
| (4, 2) | 90 | 2.92 |
| (7, 5) | 88 | 2.86 |
| (1, 3) | 88 | 2.86 |
| (6, 4) | 82 | 2.66 |
| (1, 6) | 74 | 2.40 |
| (5, 6) | 72 | 2.34 |
| (6, 5) | 71 | 2.31 |
| (6, 7) | 67 | 2.18 |
| (3, 5) | 61 | 1.98 |
| (5, 4) | 54 | 1.75 |
| (5, 7) | 52 | 1.69 |
Minor#
utils.sorted_gram_counts(full_grams_minor, 2)
N = 2994
| count | % | |
|---|---|---|
| progression | ||
| (5, 1) | 385 | 12.86 |
| (4, 5) | 249 | 8.32 |
| (1, ∅) | 198 | 6.61 |
| (1, 5) | 196 | 6.55 |
| (#7, 1) | 161 | 5.38 |
| (1, 4) | 144 | 4.81 |
| (3, 2) | 128 | 4.28 |
| (4, 3) | 126 | 4.21 |
| (3, 4) | 108 | 3.61 |
| (6, 5) | 105 | 3.51 |
| (6, 4) | 103 | 3.44 |
| (2, 1) | 101 | 3.37 |
| (5, 3) | 100 | 3.34 |
| (5, 4) | 93 | 3.11 |
| (3, 1) | 85 | 2.84 |
| (2, 3) | 84 | 2.81 |
| (1, #7) | 84 | 2.81 |
| (4, 2) | 83 | 2.77 |
| (5, 6) | 81 | 2.71 |
| (#7, 5) | 79 | 2.64 |
| (2, 5) | 73 | 2.44 |
| (1, 6) | 65 | 2.17 |
| (1, 3) | 61 | 2.04 |
| (1, 7) | 53 | 1.77 |
| (1, 2) | 49 | 1.64 |
Most frequent 3-grams#
Major#
utils.sorted_gram_counts(full_grams_major, 3)
N = 1483
| count | % | |
|---|---|---|
| progression | ||
| (5, 1, ∅) | 169 | 11.40 |
| (1, 5, 1) | 135 | 9.10 |
| (4, 5, 1) | 120 | 8.09 |
| (5, 1, 5) | 76 | 5.12 |
| (3, 2, 1) | 66 | 4.45 |
| (7, 1, 5) | 58 | 3.91 |
| (7, 5, 1) | 55 | 3.71 |
| (5, 1, 7) | 54 | 3.64 |
| (6, 7, 1) | 53 | 3.57 |
| (3, 4, 5) | 52 | 3.51 |
| (1, 7, 1) | 50 | 3.37 |
| (4, 3, 2) | 49 | 3.30 |
| (1, 4, 5) | 48 | 3.24 |
| (6, 4, 5) | 47 | 3.17 |
| (5, 3, 1) | 46 | 3.10 |
| (3, 5, 1) | 44 | 2.97 |
| (5, 1, 4) | 44 | 2.97 |
| (2, 5, 1) | 43 | 2.90 |
| (5, 4, 3) | 42 | 2.83 |
| (3, 1, 4) | 40 | 2.70 |
| (4, 2, 5) | 40 | 2.70 |
| (2, 1, 5) | 39 | 2.63 |
| (3, 1, 5) | 38 | 2.56 |
| (1, 4, 2) | 38 | 2.56 |
| (1, 7, 6) | 37 | 2.49 |
Minor#
utils.sorted_gram_counts(full_grams_minor, 3)
N = 1488
| count | % | |
|---|---|---|
| progression | ||
| (5, 1, ∅) | 165 | 11.09 |
| (4, 5, 1) | 140 | 9.41 |
| (1, 5, 1) | 108 | 7.26 |
| (3, 2, 1) | 77 | 5.17 |
| (6, 4, 5) | 75 | 5.04 |
| (3, 4, 5) | 72 | 4.84 |
| (5, 4, 3) | 65 | 4.37 |
| (5, 1, 5) | 61 | 4.10 |
| (#7, 1, 5) | 61 | 4.10 |
| (1, 4, 5) | 60 | 4.03 |
| (#7, 5, 1) | 59 | 3.97 |
| (4, 3, 2) | 58 | 3.90 |
| (1, #7, 1) | 54 | 3.63 |
| (5, 1, 4) | 46 | 3.09 |
| (1, 7, 6) | 43 | 2.89 |
| (2, 1, 5) | 39 | 2.62 |
| (4, 5, 6) | 37 | 2.49 |
| (5, 6, 4) | 36 | 2.42 |
| (4, 2, 5) | 35 | 2.35 |
| (7, 6, 5) | 34 | 2.28 |
| (6, 5, 4) | 34 | 2.28 |
| (2, 1, #7) | 33 | 2.22 |
| (3, 1, 4) | 32 | 2.15 |
| (4, 3, 4) | 32 | 2.15 |
| (1, 6, 4) | 32 | 2.15 |
Most frequent 4-grams#
Major#
utils.sorted_gram_counts(full_grams_major, 4)
N = 701
| count | % | |
|---|---|---|
| progression | ||
| (4, 5, 1, ∅) | 63 | 8.99 |
| (1, 5, 1, ∅) | 54 | 7.70 |
| (5, 1, 5, 1) | 45 | 6.42 |
| (1, 4, 5, 1) | 41 | 5.85 |
| (6, 4, 5, 1) | 39 | 5.56 |
| (4, 3, 2, 1) | 36 | 5.14 |
| (1, 5, 1, 5) | 36 | 5.14 |
| (3, 4, 5, 1) | 35 | 4.99 |
| (7, 1, 5, 1) | 28 | 3.99 |
| (3, 1, 5, 1) | 25 | 3.57 |
| (3, 5, 1, ∅) | 24 | 3.42 |
| (1, 7, 6, 5) | 23 | 3.28 |
| (4, 5, 1, 5) | 23 | 3.28 |
| (3, 2, 1, 5) | 22 | 3.14 |
| (5, 6, 7, 1) | 22 | 3.14 |
| (1, 7, 1, 5) | 20 | 2.85 |
| (5, 1, 4, 5) | 20 | 2.85 |
| (5, 6, 4, 5) | 19 | 2.71 |
| (2, 1, 5, 1) | 19 | 2.71 |
| (5, 3, 1, 5) | 18 | 2.57 |
| (7, 1, 7, 1) | 18 | 2.57 |
| (7, 1, 3, 4) | 18 | 2.57 |
| (7, 5, 1, 7) | 18 | 2.57 |
| (3, 1, 4, 2) | 18 | 2.57 |
| (5, 3, 2, 1) | 17 | 2.43 |
Minor#
utils.sorted_gram_counts(full_grams_minor, 4)
N = 744
| count | % | |
|---|---|---|
| progression | ||
| (4, 5, 1, ∅) | 88 | 11.83 |
| (1, 5, 1, ∅) | 45 | 6.05 |
| (3, 4, 5, 1) | 43 | 5.78 |
| (1, 4, 5, 1) | 43 | 5.78 |
| (6, 4, 5, 1) | 40 | 5.38 |
| (4, 3, 2, 1) | 38 | 5.11 |
| (5, 4, 3, 2) | 34 | 4.57 |
| (5, 1, 5, 1) | 33 | 4.44 |
| (5, 6, 4, 5) | 31 | 4.17 |
| (1, 7, 6, 5) | 30 | 4.03 |
| (#7, 1, 5, 1) | 29 | 3.90 |
| (3, 2, 1, 5) | 28 | 3.76 |
| (3, 2, 1, #7) | 25 | 3.36 |
| (2, 1, 5, 1) | 24 | 3.23 |
| (1, #7, 1, 5) | 23 | 3.09 |
| (6, 5, 4, 3) | 22 | 2.96 |
| (5, 1, 4, 5) | 22 | 2.96 |
| (2, 3, 4, 5) | 20 | 2.69 |
| (1, 6, 4, 5) | 20 | 2.69 |
| (5, 1, 7, 6) | 19 | 2.55 |
| (2, 1, #7, 1) | 19 | 2.55 |
| (4, 3, 4, 5) | 18 | 2.42 |
| (5, 1, #7, 1) | 18 | 2.42 |
| (1, 5, 1, 4) | 16 | 2.15 |
| (5, 3, 2, 1) | 16 | 2.15 |
Most frequent 5-grams#
Major#
utils.sorted_gram_counts(full_grams_major, 5)
N = 345
| count | % | |
|---|---|---|
| progression | ||
| (1, 4, 5, 1, ∅) | 26 | 7.54 |
| (1, 5, 1, 5, 1) | 24 | 6.96 |
| (5, 1, 5, 1, 5) | 22 | 6.38 |
| (6, 4, 5, 1, ∅) | 17 | 4.93 |
| (2, 1, 5, 1, ∅) | 17 | 4.93 |
| (3, 4, 5, 1, ∅) | 16 | 4.64 |
| (5, 6, 4, 5, 1) | 16 | 4.64 |
| (5, 1, 4, 5, 1) | 16 | 4.64 |
| (5, 3, 1, 5, 1) | 15 | 4.35 |
| (7, 1, 4, 5, 1) | 14 | 4.06 |
| (1, 5, 6, 4, 5) | 13 | 3.77 |
| (7, 1, 5, 1, ∅) | 12 | 3.48 |
| (4, 5, 1, 5, 1) | 12 | 3.48 |
| (4, 3, 4, 5, 1) | 11 | 3.19 |
| (1, 4, 3, 2, 1) | 11 | 3.19 |
| (7, 5, 1, 7, 5) | 11 | 3.19 |
| (1, 6, 4, 5, 1) | 11 | 3.19 |
| (4, 3, 2, 1, 5) | 11 | 3.19 |
| (3, 2, 1, 5, 1) | 11 | 3.19 |
| (5, 4, 3, 2, 1) | 10 | 2.90 |
| (5, 1, 7, 5, 1) | 10 | 2.90 |
| (1, 7, 5, 1, 7) | 10 | 2.90 |
| (3, 1, 5, 1, ∅) | 10 | 2.90 |
| (7, 1, 7, 6, 5) | 10 | 2.90 |
| (1, 4, 3, 5, 1) | 9 | 2.61 |
Minor#
utils.sorted_gram_counts(full_grams_minor, 5)
N = 363
| count | % | |
|---|---|---|
| progression | ||
| (3, 4, 5, 1, ∅) | 29 | 7.99 |
| (6, 4, 5, 1, ∅) | 25 | 6.89 |
| (1, 4, 5, 1, ∅) | 25 | 6.89 |
| (3, 2, 1, 5, 1) | 20 | 5.51 |
| (5, 4, 3, 2, 1) | 19 | 5.23 |
| (5, 6, 4, 5, 1) | 18 | 4.96 |
| (5, 1, 4, 5, 1) | 18 | 4.96 |
| (4, 3, 4, 5, 1) | 15 | 4.13 |
| (3, 2, 1, #7, 1) | 15 | 4.13 |
| (4, 3, 2, 1, 5) | 14 | 3.86 |
| (4, 3, 2, 1, #7) | 13 | 3.58 |
| (6, 5, 4, 3, 2) | 13 | 3.58 |
| (1, 5, 1, #7, 1) | 12 | 3.31 |
| (5, 1, 5, 1, ∅) | 12 | 3.31 |
| (5, 1, #7, 1, 5) | 11 | 3.03 |
| (#7, 1, 5, 1, ∅) | 11 | 3.03 |
| (2, 1, 5, 1, ∅) | 11 | 3.03 |
| (5, 1, 7, 6, 5) | 11 | 3.03 |
| (3, 1, 4, 2, 5) | 11 | 3.03 |
| (4, 5, 6, 4, 5) | 10 | 2.75 |
| (#7, 5, 1, 4, 5) | 10 | 2.75 |
| (2, 3, 4, 5, 1) | 10 | 2.75 |
| (#7, 1, 3, 4, 5) | 10 | 2.75 |
| (1, 3, 4, 5, 1) | 10 | 2.75 |
| (1, 4, 3, 2, 1) | 10 | 2.75 |